package net.wofly.sale.report.service.impl;

import net.wofly.cashier.order.util.PayType;
import net.wofly.common.persistence.PageWrapper;
import net.wofly.common.util.DateUtil;
import net.wofly.common.util.PageHelper;
import net.wofly.common.util.ResultCode;
import net.wofly.common.util.ReturnBean;
import net.wofly.right.domain.Customer;
import net.wofly.right.domain.User;
import net.wofly.right.service.ICustomerService;
import net.wofly.right.service.IUserService;
import net.wofly.sale.commodity.domain.Commodity;
import net.wofly.sale.commodity.domain.CommodityTerminal;
import net.wofly.sale.commodity.service.ICommodityChannelService;
import net.wofly.sale.commodity.service.ICommodityTmlService;
import net.wofly.sale.order.domain.Gift;
import net.wofly.sale.order.domain.Order;
import net.wofly.sale.order.domain.OrderContent;
import net.wofly.sale.order.domain.PayInfo;
import net.wofly.sale.order.service.IGiftService;
import net.wofly.sale.order.service.IPayInfoService;
import net.wofly.sale.order.service.ISaleOrderContentService;
import net.wofly.sale.order.service.ISaleOrderService;
import net.wofly.sale.report.domain.CardExchangeDailyReport;
import net.wofly.sale.report.domain.SaleDailyReport;
import net.wofly.sale.report.domain.SaleStockDailyReport;
import net.wofly.sale.report.dto.*;
import net.wofly.sale.report.repository.SaleDailyReportRepository;
import net.wofly.sale.report.service.ICardExchangeDailyReportService;
import net.wofly.sale.report.service.ISaleDailyReportService;
import net.wofly.sale.report.service.ISaleStockDailyReportService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.transaction.Transactional;
import java.util.*;
import java.util.stream.Collectors;

@Service("iSaleDailyReportService")
@Transactional
public class SaleDailyReportServiceImpl implements ISaleDailyReportService {
    
    @Autowired
    JdbcTemplate jdbcTemplate;
    
    @Autowired
    SaleDailyReportRepository saleDailyReportRepository;
    @Autowired
    ISaleStockDailyReportService iSaleStockDailyReportService;
    @Autowired
    ICardExchangeDailyReportService iCardExchangeDailyReportService;
    @Autowired
    ISaleOrderService iSaleOrderService;
    @Autowired
    ISaleOrderContentService iSaleOrderContentService;
    @Autowired
    ICommodityChannelService iCommodityChannelService;
    @Autowired
    ICommodityTmlService iCommodityTmlService;
    @Autowired
    IUserService iUserService;
    @Autowired
    IPayInfoService iPayInfoService;
    
    @Autowired
    IGiftService iGiftService;
    @Autowired
    ICustomerService iCustomerService;
    
    @Override
    public SaleDailyReport save(SaleDailyReport entity) {
        return saleDailyReportRepository.save(entity);
    }
    
    @Override
    public void delete(SaleDailyReport entity) {
        saleDailyReportRepository.delete(entity);
    }
    
    @Override
    public void delete(String key) {
        saleDailyReportRepository.delete(key);
    }
    
    @Override
    public SaleDailyReport findOne(String key) {
        return saleDailyReportRepository.findOne(key);
    }
    
    @Override
    public List<SaleDailyReport> save(List<SaleDailyReport> entityList) {
        return (List<SaleDailyReport>) saleDailyReportRepository.save(entityList);
    }
    
    /**
     * 根据日期查询日报
     *
     * @param countDate
     * @return
     */
    @Override
    public ReturnBean<PageWrapper<SaleDailyReport>> findSaleDailyReportByDate(
            Long countDate, Integer pageNum, Integer pageSize) throws InterruptedException {
        Pageable pageable = new PageRequest(pageNum - 1, pageSize);
        Page<SaleDailyReport> page = saleDailyReportRepository.findByCountDate(countDate, pageable);
//        if(CollectionUtils.isEmpty(page.getContent())){
//            generateSaleDailyReport(countDate);
//            page = saleDailyReportRepository.findByCountDate(countDate, pageable);
//        }
        return new ReturnBean<>(ResultCode.SUCCESS, "查询成功", PageHelper.toPage(page));
    }
    
    @Override
    public void generateSaleDailyReport(Long countDate) {
        saleDailyReportRepository.deleteByCountDate(countDate);
        String countDateStr = DateUtil.getDateToString(new Date(countDate), "yyyy-MM-dd");
        jdbcTemplate.execute("call proc_sale_daily_report('"+countDateStr+"');");
    }

    @Override
    public ReturnBean<DailyReportDetailDTO> getSaleDailyReportDetail(String userID, Long countDate) {
        SaleDailyReport saleDailyReport;
        List<SaleDailyReport> saleDailyReports = saleDailyReportRepository.findByUserIDAndCountDate(userID, countDate) ;
        if (null == saleDailyReports || saleDailyReports.isEmpty()) {
            saleDailyReport = new SaleDailyReport();
        } else {
            saleDailyReport = saleDailyReports.get(0);
        }

        List<SaleStockDailyReport> saleStockDailyReports = iSaleStockDailyReportService.findByUserIDAndCountDate(userID, countDate);

        List<CardExchangeDailyReport> cardExchangeDailyReports = iCardExchangeDailyReportService.findByUserIDAndCountDate(userID, countDate);

        Long startTime = countDate;
        Date countDateDate = new Date(countDate);
        Long endTime = DateUtil.processEndTime(countDateDate).getTime();
        List<Order> commitOrders = iSaleOrderService.findByBuyerAndOrderCommitTimeBetween(userID, startTime, endTime);
        List<Order> finishedOrders = iSaleOrderService.findByBuyerAndFinishedTimeBetween(userID, startTime, endTime);
        List<Order> payOrders = iSaleOrderService.findByBuyerAndPayTimeBetween(userID, startTime, endTime);

        Set<Order> orderSet = new HashSet<>(commitOrders);
        orderSet.addAll(finishedOrders);
        orderSet.addAll(payOrders);

        if (orderSet.size() == 0) {
            return new ReturnBean<>(ResultCode.SUCCESS, "查询成功");
        }

        List<OrderDTO> orderDTOList = new ArrayList<>(orderSet.size());
        for (Order order : orderSet) {
            OrderDTO orderDTO = new OrderDTO();
            orderDTO.setOrderID(order.getOrderID());
            orderDTO.setOrderNo(order.getOrderNo());
            String customerUserID = order.getCustomerUserID();
            orderDTO.setCustomerUserID(order.getCustomerUserID());
            Customer customer = iCustomerService.findOne(customerUserID);
            if (customer == null) {
                return new ReturnBean<>(ResultCode.ERROR_SERVICE, "未找到用户："+ customerUserID +"！");
            }
            orderDTO.setCustomerUserName(customer.getCustomerName());
            PayInfo payInfo = iPayInfoService.findByOrderIDOrderByPayTimeDesc(order.getOrderID());
            if (payInfo != null && payInfo.getPayType().equals(PayType.白条支付.getValue())) {
                orderDTO.setIsWhiteBar("是");
            } else {
                orderDTO.setIsWhiteBar("否");
            }
            orderDTO.setRealPrice(order.getRealPrice());
            List<OrderContent> orderContents = order.getOrderContents();
            List<OrderContentDTO> orderContentDTOs = new ArrayList<>(orderContents.size());
            for (OrderContent orderContent : orderContents) {
                String commodityName = iCommodityChannelService.findCommodityNameByCommodityChannelID(orderContent.getCommodityChannelID());
                if (commodityName == null) {
                    return new ReturnBean<>(ResultCode.ERROR_SERVICE, "未找到对应的商品！");
                }
                OrderContentDTO orderContentDTO = new OrderContentDTO();
                orderContentDTO.setCommodityName(commodityName);
                orderContentDTO.setNum(orderContent.getNum());
                orderContentDTO.setPrice(orderContent.getPrice());
                orderContentDTOs.add(orderContentDTO);
            }
            orderDTO.setOrderContentDTOList(orderContentDTOs);
            //Set<Gift> gifts = order.getGifts();
            List<Gift> gifts = iGiftService.findByOrderID(order.getOrderID());
            List<GiftDTO> giftDTOs = new ArrayList<>(gifts.size());
            for (Gift gift : gifts) {
                CommodityTerminal terminal = iCommodityTmlService.findOne(gift.getCommodityTerminalID());
                if (terminal == null) {
                    return new ReturnBean<>(ResultCode.ERROR_SERVICE, "未找到对应的赠品！");
                }
                GiftDTO giftDTO = new GiftDTO();
                giftDTO.setGiftName(terminal.getCommodityTerminalName());
                giftDTO.setGiftNum(gift.getNum());
                giftDTOs.add(giftDTO);
            }
            orderDTO.setGiftDTOList(giftDTOs);
            orderDTOList.add(orderDTO);
        }

        List<StockDTO> stockDTOs = null;
        User user = iUserService.findOne(userID);
        if (user != null && StringUtils.isNotBlank(user.getWarehouseID())) {
            stockDTOs = this.commodityTerminalOutStockSummary(user.getWarehouseID(), countDate).getResult();
        }

        if (orderDTOList == null) {
            orderDTOList = new ArrayList<>(0);
        }

        if (saleStockDailyReports == null) {
            saleStockDailyReports = new ArrayList<>(0);
        }

        if (cardExchangeDailyReports == null) {
            cardExchangeDailyReports = new ArrayList<>(0);
        }

        if (stockDTOs == null) {
            stockDTOs = new ArrayList<>(0);
        }

        DailyReportDetailDTO dailyReportDetailDTO = new DailyReportDetailDTO(orderDTOList, saleStockDailyReports,
                cardExchangeDailyReports, stockDTOs, saleDailyReport);
        return new ReturnBean<>(ResultCode.SUCCESS, "查询成功", dailyReportDetailDTO);
    }

	@Override
	public ReturnBean<SaleDailyReport> findMyDailyReportByDate(String userID ,Long countDate) {
		
		List<SaleDailyReport> saleDailyReports = saleDailyReportRepository.findByUserIDAndCountDate(userID, countDate) ;
		if (null == saleDailyReports || saleDailyReports.isEmpty()) {
			return new ReturnBean<>(-1, "个人日报还未生成！") ;
		}
        return new ReturnBean<>(ResultCode.SUCCESS, "查询成功", saleDailyReports.get(0));
	}

    @Override
    public ReturnBean<List<StockDTO>> managerOutStockSummary(Long countDate) {
        Date countDateDate = new Date(countDate);
        Long endTime = DateUtil.processEndTime(countDateDate).getTime();
        List<List<Object>> objects = saleDailyReportRepository.managerOutStockSummary(countDate, endTime);
        return new ReturnBean<>(ResultCode.SUCCESS, "查询成功！", transferToStockDTO(objects));
    }

    @Override
    public ReturnBean<List<StockDTO>> storeOutStockSummary(Long countDate) {
        Date countDateDate = new Date(countDate);
        Long endTime = DateUtil.processEndTime(countDateDate).getTime();
        List<List<Object>> objects = saleDailyReportRepository.storeOutStockSummary(countDate, endTime);
        return new ReturnBean<>(ResultCode.SUCCESS, "查询成功！", transferToStockDTO(objects));
    }

    @Override
    public ReturnBean<List<StockDTO>> managerInStockSummary(Long countDate) {
        Date countDateDate = new Date(countDate);
        Long endTime = DateUtil.processEndTime(countDateDate).getTime();
        List<List<Object>> objects = saleDailyReportRepository.managerInStockSummary(countDate, endTime);
        return new ReturnBean<>(ResultCode.SUCCESS, "查询成功！", transferToStockDTO(objects));
    }

    private List<StockDTO> transferToStockDTO(List<List<Object>> objects){
        List<StockDTO> dtoList = new ArrayList<>(objects.size());
        for (Object obj: objects) {
            Object[] objArr = (Object[]) obj;
            StockDTO stockDTO = new StockDTO();
            stockDTO.setId(String.valueOf(objArr[0]));
            stockDTO.setName(String.valueOf(objArr[1]));
            stockDTO.setCommodityTerminalID(String.valueOf(objArr[2]));
            stockDTO.setCommodityTerminalName(String.valueOf(objArr[3]));
            stockDTO.setSumNum(Long.valueOf(String.valueOf(objArr[4])));
            stockDTO.setCommodity(iCommodityTmlService.findCommodityByCommodityTerminalID(stockDTO.getCommodityTerminalID())) ;
            dtoList.add(stockDTO);
        }
        return dtoList;
    }

    @Override
    public ReturnBean<List<StockDTO>> storeInStockSummary(Long countDate) {
        Date countDateDate = new Date(countDate);
        Long endTime = DateUtil.processEndTime(countDateDate).getTime();
        List<List<Object>> objects = saleDailyReportRepository.storeInStockSummary(countDate, endTime);
        return new ReturnBean<>(ResultCode.SUCCESS, "查询成功！", transferToStockDTO(objects));
    }

    @Override
    public ReturnBean<List<StockDTO>> commodityTerminalOutStockSummary(String warehouseID, Long countDate) {
        Date countDateDate = new Date(countDate);
        Long endTime = DateUtil.processEndTime(countDateDate).getTime();
        List<List<Object>> objects = saleDailyReportRepository.commodityTerminalOutStockSummary(warehouseID, countDate, endTime);

        List<StockDTO> dtoList = new ArrayList<>(objects.size());
        for (Object obj: objects) {
            Object[] objArr = (Object[]) obj;
            StockDTO stockDTO = new StockDTO();
            stockDTO.setCommodityTerminalID(String.valueOf(objArr[0]));
            stockDTO.setCommodityTerminalName(String.valueOf(objArr[1]));
            stockDTO.setSumNum(Long.valueOf(String.valueOf(objArr[2])));
            dtoList.add(stockDTO);
        }

        return new ReturnBean<>(ResultCode.SUCCESS, "查询成功！", dtoList);
    }

    @Override
    public ReturnBean<List<StockDTO>> commodityTerminalOutStockSummary(Long countDate) {
        Date countDateDate = new Date(countDate);
        Long endTime = DateUtil.processEndTime(countDateDate).getTime();
        List<List<Object>> objects = saleDailyReportRepository.commodityTerminalOutStockSummary(countDate, endTime);

        List<StockDTO> dtoList = new ArrayList<>(objects.size());
        for (Object obj: objects) {
            Object[] objArr = (Object[]) obj;
            StockDTO stockDTO = new StockDTO();
            stockDTO.setCommodityTerminalID(String.valueOf(objArr[0]));
            stockDTO.setCommodityTerminalName(String.valueOf(objArr[1]));
            stockDTO.setSumNum(Long.valueOf(String.valueOf(objArr[2])));
            dtoList.add(stockDTO);
        }

        return new ReturnBean<>(ResultCode.SUCCESS, "查询成功！", dtoList);
    }
}
